package com.jltx.zeus.arch

import android.app.Application
import android.util.Log
import com.jltx.zeus.arch.api.WeChatApiService
import com.jltx.zeus.arch.bean.WeChatResponse
import com.jltx.zeus.viewmodel.*
import com.jltx.zeus.viewmodel.livedata.SingleLiveEvent
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import retrofit2.await

/**
 * @author jltxseo
 *         Created by junlintianxia on 2020/05/10.
 */
class MainViewModel(ceshi: String, application: Application) : BaseAndroidViewModel(application) {
    val toastLiveData = SingleLiveEvent<String>()

    private val _wechatData = MutableStateFlow<WeChatResponse?>(WeChatResponse())
    val wechatData = _wechatData.asStateFlow()

    fun getToastMsg() {
        execute(object : ViewModelCallback<String> {
            override fun onSuccess(data: String) {
                super.onSuccess(data)
                toastLiveData.value = data
            }

            override suspend fun onSuccessIO(data: String) {
                super.onSuccessIO(data)
            }

            override fun onFail(exception: Throwable) {
                super.onFail(exception)
            }

            override fun onFinally() {
                super.onFinally()
            }
        })
        {
            "getToastMsg"
        }
    }

    fun getToastMsgDeferred() {
        executeDeferred(object : ViewModelCallback<String> {
            override fun onSuccess(data: String) {
                super.onSuccess(data)
                toastLiveData.value = data
            }

            override suspend fun onSuccessIO(data: String) {
                super.onSuccessIO(data)
            }

            override fun onStart() {
                super.onStart()
            }

            override fun onFail(exception: Throwable) {
                super.onFail(exception)
            }

            override fun onFinally() {
                super.onFinally()
            }
        })
        {
            async(Dispatchers.IO) {
                "getToastMsgDeferred"
            }
        }
    }

    fun getToastMsgProduce() {
        executeProduce(object : ViewModelCallback<String> {
            override fun onSuccess(data: String) {
                super.onSuccess(data)
                toastLiveData.value = data
            }

            override suspend fun onSuccessIO(data: String) {
                super.onSuccessIO(data)
            }

            override fun onStart() {
                super.onStart()
            }

            override fun onFail(exception: Throwable) {
                super.onFail(exception)
            }

            override fun onFinally() {
                super.onFinally()
            }
        }) {
            produce {
                var result = ProduceResult<String>()
                result.data = "getToastMsgProduce"
                result.status = ProduceResultStatus.STATUS_SUCCESS
                send(result)
                close()
            }
        }
    }


    fun getWeChatNews() {
        execute(object : ViewModelCallback<WeChatResponse?> {
            override fun onSuccess(data: WeChatResponse?) {
                Log.d(TAG, "协程返回的数据${Thread.currentThread()} $data")
                super.onSuccess(data)
            }

            override suspend fun onSuccessIO(data: WeChatResponse?) {
                Log.d(TAG, "协程返回的数据2 ${Thread.currentThread()} $data")
                super.onSuccessIO(data)
            }

            override fun onStart() {

                super.onStart()
            }

            override fun onFail(exception: Throwable) {
                super.onFail(exception)
            }

            override fun onFinally() {
                super.onFinally()
            }
        }) {
            WeChatApiService.weChatApi.getWeChatNewsDeferAsync(20, 1).await()
        }
    }

    fun getWeChatNewsFlow() {
        launchUI {
            flow {
                val list = WeChatApiService.weChatApi.getWeChatNewsDeferAsync(20, 1).await()
                emit(list)
            }.flowOn(Dispatchers.Default)
                .map {
                    it
                }.flowOn(Dispatchers.IO).catch { e ->
                    Log.d(TAG, "协程返回的数错误${Thread.currentThread()} ${e}")
                }.onCompletion {
                    Log.d(TAG, "协程执行结束${Thread.currentThread()}")
                }
                .collect {
                    _wechatData.value = it
                    Log.d(TAG, "协程返回的数据${Thread.currentThread()} $it")
                }
        }
    }

    fun getWeChatNewsRxJava() {
        getWeChatNewsRxJava(object : ViewModelCallback<WeChatResponse> {
            override fun onSuccess(data: WeChatResponse) {
                Log.d(TAG, "Rxjava返回的数据$data ${Thread.currentThread()}")
                super.onSuccess(data)
            }

            override suspend fun onSuccessIO(data: WeChatResponse) {
                super.onSuccessIO(data)
            }

            override fun onStart() {
                super.onStart()
            }

            override fun onFail(exception: Throwable) {
                super.onFail(exception)
            }

            override fun onFinally() {
                super.onFinally()
            }
        })
    }


    private fun getWeChatNewsRxJava(callback: ViewModelCallback<WeChatResponse>?) {
        WeChatApiService.weChatApi.getWeChatNews(20, 1)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<WeChatResponse?> {
                override fun onSubscribe(d: Disposable?) {
                    callback?.onStart()
                }

                override fun onNext(t: WeChatResponse?) {
                    t?.apply {
                        callback?.onSuccess(this)
                    }

                }

                override fun onError(e: Throwable?) {
                    e?.apply {
                        callback?.onFail(this)
                    }
                }

                override fun onComplete() {
                    callback?.onFinally()
                }
            })
    }

    companion object {
        private const val TAG = "MainViewModel"
    }
}